home *** CD-ROM | disk | FTP | other *** search
-
- /* xlread - xlisp expression input routine */
-
- #ifdef CI_86
- #include "a:stdio.h"
- #include "xlisp.h"
- #endif
-
- #ifdef AZTEC
- #include "a:stdio.h"
- #include "xlisp.h"
- #endif
-
- #ifdef unix
- #include <stdio.h>
- #include <ctype.h>
- #include <xlisp.h>
- #endif
-
- /* global variables */
-
- struct node *oblist;
-
- /* external variables */
-
- extern struct node *xlstack;
- extern int (*xlgetc)();
- extern int xlplevel;
-
- /* local variables */
-
- static int savech;
-
- /* forward declarations (the extern hack is for decusc) */
-
- extern struct node *parse();
- extern struct node *plist();
- extern struct node *pstring();
- extern struct node *pnumber();
- extern struct node *pquote();
- extern struct node *pname();
-
- #ifdef REALS
- extern struct node *pfloat();
- #endif
-
- /**************************************
- * xlread - read an xlisp expression *
- **************************************/
-
- struct node *xlread()
- {
- savech = -1; /* initialize */
- xlplevel = 0;
-
- return (parse()); /* Parse an expression */
- }
-
-
- /**************************************
- * parse - parse an xlisp expression *
- **************************************/
-
- static struct node *parse()
- {
- int ch;
-
- while (TRUE) /* Look for a node, skipp comments */
- {
- switch (ch = nextch()) /* Switch on next character */
- {
- case '\'': /* a quoted expression */
- return (pquote());
-
- case '(': /* a sublist */
- return (plist());
-
- case ')': /* closing paren - shouldn't happen */
- xlfail("extra right paren");
-
- case '.':
- #ifdef REALS
- return (pfloat(0)); /* Real fractional only */
- #else
- xlfail("misplaced dot");/* dot - shouldn't happen */
- #endif
-
- case ';': /* a comment */
- pcomment();
- break;
-
- case '"': /* a string */
- return (pstring());
-
- default:
- if (isdigit(ch)) /* a number */
- return (pnumber(1));
- else if (issym(ch)) /* a name */
- return (pname());
- else
- xlfail("invalid character");
- }
- }
- }
-
-
- /*******************************
- * pcomment - parse a comment *
- *******************************/
-
- static pcomment()
- {
- while (getch() != '\n') /* Skip to end of line */
- ;
- }
-
-
- /*************************
- * plist - parse a list *
- *************************/
-
- static struct node *plist()
- {
- struct node *oldstk,val,*lastnptr,*nptr;
- int ch;
-
- xlplevel += 1; /* Increment nesting level */
- oldstk = xlsave(&val,NULL); /* Create .... */
- savech = -1; /* Skip opend paren */
-
- /* keep appending nodes until a closing paren is found */
- for (lastnptr = NULL; (ch = nextch()) > 0 && ch != ')'; lastnptr = nptr)
- {
- if (ch == '.') /* Check for a dotted pair */
- {
- savech = -1; /* Skip the dot */
-
- if (lastnptr == NULL) /* Make sure there is a node */
- xlfail("invalid dotted pair");
-
- lastnptr->n_listnext = parse(); /* Parse expression */
-
- if (nextch() != ')') /* Check for closing paren */
- xlfail("invalid dotted pair");
-
- break; /* Done with this list */
- }
-
- nptr = newnode(LIST); /* Allocate and link new node */
- if (lastnptr == NULL)
- val.n_ptr = nptr;
- else
- lastnptr->n_listnext = nptr;
-
- nptr->n_listvalue = parse(); /* Initialize it */
- }
-
- savech = -1; /* Skip the closing paren */
-
- xlstack = oldstk; /* Restore previous stack frame */
- xlplevel -= 1; /* Decrement nesting level */
-
- return (val.n_ptr); /* Successful return */
- }
-
- /*****************************
- * pstring - parse a string *
- *****************************/
-
- static struct node *pstring()
- {
- struct node *oldstk,val;
- char sbuf[STRMAX+1];
- int ch,i,d1,d2,d3;
-
- oldstk = xlsave(&val,NULL); /* Create a new stack frame */
- savech = -1; /* Skip opening quote */
-
- /* loop looking for a closing qte */
- for (i = 0; i < STRMAX && (ch = getch()) != '"'; i++)
- {
- switch (ch)
- {
- case '\\':
- switch (ch = getch())
- {
- case 'e':
- ch = '\033';
- break;
-
- case 'n':
- ch = '\n';
- break;
-
- case 'r':
- ch = '\r';
- break;
-
- case 't':
- ch = '\t';
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- d1 = ch - '0';
- while (((ch = getch()) >= '0') && (ch < '8'))
- d1 = d1 <<3 + (ch - '0');
- ch = d1;
- break;
-
- default:
- break;
- }
- }
- sbuf[i] = ch;
- }
- sbuf[i] = 0;
-
- val.n_ptr = newnode(STR); /* Initialize the node */
- val.n_ptr->n_str = strsave(sbuf);
-
- xlstack = oldstk; /* Restore old stack frame */
- return (val.n_ptr); /* .. and return */
- }
-
-
- #ifdef REALS
- /********************************************************
- * pfloat - parse the fractional part of a real number *
- ********************************************************/
-
- static struct node *pfloat(i)
- int i;
- {
- struct node *val;
- int ch;
- long float rval = (float) ((i<0) ? -i : i), fp= 1;
-
- for ( ; isdigit(ch = thisch()); savech = -1)
- rval = rval + (ch - '0')/(fp *= 10);
-
- if (issym(ch)) /* ensure correct termination */
- xlfail("badly formed number");
-
- val = newnode(REAL); /* Initialze the new node */
- val->n_real = (i < 0) ? -rval : rval;
-
- return (val);
- }
- #endif
-
- /*****************************
- * pnumber - parse a number *
- *****************************/
-
- static struct node *pnumber(sign)
- int sign;
- {
- struct node *val;
- int ch,ival = 0;
-
- for ( ; isdigit(ch = thisch()); savech = -1) /* loop while digits */
- ival = ival * 10 + ch - '0';
-
- #ifdef REALS
- if (ch == '.')
- {
- savech = -1;
- return pfloat(sign*ival);
- }
- #endif
-
- if (issym(ch)) /* ensure correct termination */
- xlfail("badly formed number");
-
- val = newnode(INT); /* Initialze the new node */
- val->n_int = sign * ival;
-
- return (val);
- }
-
- /***************************************************
- * xlenter - enter a symbol into the symbol table *
- ***************************************************/
-
- struct node *xlenter(sname)
- char *sname;
- {
- struct node *sptr;
-
- if (strcmp(sname,"nil") == 0) /* Check for nil */
- return (NULL);
-
- if (oblist == NULL) /* Create oblist if required */
- {
- oblist = newnode(SYM);
- oblist->n_symname = strsave("oblist");
- oblist->n_symvalue = newnode(LIST);
- oblist->n_symvalue->n_listvalue = oblist;
- }
-
- sptr = oblist->n_symvalue; /* check for symbol already in table */
- while (sptr != NULL)
- {
- if (sptr->n_listvalue == NULL)
- {
- printf("bad oblist\n");
- sptr = oblist->n_symvalue;
- while (sptr != NULL)
- {
- if (sptr->n_listvalue == NULL)
- xlfail("end oblist");
- printf("\n%s",sptr->n_listvalue->n_symname);
- sptr = sptr->n_listnext;
- }
- }
- else if (sptr->n_listvalue->n_symname == NULL)
- printf("bad oblist symbol\n");
- else
- if (strcmp(sptr->n_listvalue->n_symname,sname) == 0)
- return (sptr->n_listvalue);
- sptr = sptr->n_listnext;
- }
-
- sptr = newnode(LIST); /* Create and link new symbol */
- sptr->n_listnext = oblist->n_symvalue;
- oblist->n_symvalue = sptr;
- sptr->n_listvalue = newnode(SYM);
- sptr->n_listvalue->n_symname = strsave(sname);
-
- return (sptr->n_listvalue);
- }
-
-
- /***************************************
- * pquote - parse a quoted expression *
- ***************************************/
-
- static struct node *pquote()
- {
- struct node *oldstk,val;
-
- oldstk = xlsave(&val,NULL); /* Create new stack frame */
- savech = -1; /* Skip the quote character */
-
- val.n_ptr = newnode(LIST); /* Allocate two new nodes */
- val.n_ptr->n_listvalue = xlenter("quote");
- val.n_ptr->n_listnext = newnode(LIST);
- val.n_ptr->n_listnext->n_listvalue = parse();
-
- xlstack = oldstk; /* Restore old stack frame */
- return (val.n_ptr); /* .. return quoted expression */
- }
-
-
- /********************************
- * pname - parse a symbol name *
- ********************************/
-
- static struct node *pname()
- {
- char sname[STRMAX+1];
- int ch,i;
-
- ch = sname[0] = getch(); /* Get first character */
- if (ch == '+' || ch == '-') /* Check for signed number */
- {
- if (isdigit(thisch()))
- return (pnumber(ch == '+' ? 1 : -1));
- }
-
- for (i = 1; i < STRMAX && issym(thisch()); i++) /* get symbol name */
- sname[i] = getch();
- sname[i] = 0;
-
- return (xlenter(sname)); /* Initialize value */
- }
-
-
- /**************************************************
- * nextch - look at the next non-blank character *
- **************************************************/
-
- static int nextch()
- {
- while (isspace(thisch())) /* Find non blank character */
- savech = -1;
-
- return savech; /* .. and return it */
- }
-
-
- /*******************************************
- * thisch - look at the current character *
- *******************************************/
-
- static int thisch()
- {
- return (savech = getch()); /* return and save next character */
- }
-
-
- /***********************************
- * getch - get the next character *
- ***********************************/
-
- static int getch()
- {
- int ch;
-
- if ((ch = savech) >= 0) /* Check for saved character */
- savech = -1;
- else
- ch = (*xlgetc)();
-
- if (ch == EOF) /* Check for abort character */
- if (xlplevel > 0)
- {
- putchar('\n');
- xltin(FALSE);
- xlfail("input aborted");
- }
- else
- exit();
-
- return (ch); /* Return char */
- }
-
-
- /****************************************************************
- * issym - check whether a character if valid in a symbol name *
- ****************************************************************/
-
- static int issym(ch)
- int ch;
- {
- if (isspace(ch))
- return FALSE;
-
- switch (ch)
- {
- case ' ':
- case '(':
- case ')':
- case ';':
- case '.':
- case '"':
- case '\\':
- return (FALSE);
-
- default:
- return (TRUE);
- }
- }